package net.hnilica.cisteniulic.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import net.hnilica.cisteniulic.dto.Osoba;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import org.apache.shiro.crypto.hash.Hash;
import org.apache.shiro.crypto.hash.Sha1Hash;
import org.apache.shiro.crypto.hash.Sha512Hash;

/**
 *
 */
public class OsobaDAO {

    private static EntityManagerFactory emf = Emf.getInstance();
    private static final String salt = "maminka";
    protected Logger log = Logger.getLogger(getClass().getName());

    /**
     */
    public Osoba getOsobaWOHesloAktHex(String email) {
        EntityManager em = emf.createEntityManager();
        try {
            Osoba osoba = new Osoba();
            Query query = em.createNativeQuery("SELECT id,email,naposledy_poslano FROM " + DAO.t(Osoba.class) + " WHERE email = ?1 ");
            query.setParameter(1, email);
            Iterator results = query.getResultList().iterator();
            while (results.hasNext()) {
                Object[] row = (Object[]) results.next();
                int id = Integer.valueOf((Integer) row[0]);
                osoba.setEmail((String) row[1]);
                Date napPos = new Date(((Timestamp) row[2]).getTime());
                osoba.setId(id);
                osoba.setNapPos(napPos);
            }
            return osoba;
        } catch (Exception e) {
            log.log(Level.WARNING, e.getMessage());
            return new Osoba();
        } finally {
            em.close();
        }
    }

    /**
     * TODO uneused untest
     */
    public List<Osoba> getAllOsobyWOHesloAktHash() {
        EntityManager em = emf.createEntityManager();
        try {
            List<Osoba> listOsoba = new ArrayList<Osoba>();
            Query query = em.createNativeQuery("SELECT id,email,naposledy_poslano FROM  " + DAO.t(Osoba.class));
            List list = query.getResultList();
            for (Iterator it = list.iterator(); it.hasNext();) {
                Object[] record = (Object[]) it.next();
                Osoba osoba = new Osoba();
                for (int i = 0; i < record.length; i++) {
                    Object row = (Object) record[i];
                    if (i == 0) {
                        int id = Integer.valueOf((Integer) row);
                        osoba.setId(id);
                    } else if (i == 1) {
                        if (row == null) {
                            osoba.setEmail("");
                        } else {
                            osoba.setEmail((String) row);
                        }
                    } else if (i == 2) {
                        if (row == null) {
                            osoba.setNapPos(new Date(1));
                        } else {
                            Date napPos = new Date(((Timestamp) row).getTime());
                            osoba.setNapPos(napPos);
                        }
                    }
                }
                listOsoba.add(osoba);
            }

            return listOsoba;
        } catch (Exception e) {
            log.log(Level.WARNING, e.getMessage());
            return new ArrayList<Osoba>();
        } finally {
            em.close();
        }
    }

    public boolean deleteOsoba(Osoba osoba) {
        EntityManager em = emf.createEntityManager();
        boolean ok = true;
        try {
            em.getTransaction().begin();
            em.remove(osoba);
            em.getTransaction().commit();

            return ok;
        } catch (Exception e) {
            log.log(Level.WARNING, e.getMessage());
            em.getTransaction().rollback();
            ok = false;
            return ok;
        } finally {
            em.close();
        }
    }

    public boolean saveOsoba(Osoba osoba) {
        EntityManager em = emf.createEntityManager();
        try {
            String email = osoba.getEmail();
            String password = osoba.getHeslo();
            Hash passHash = new Sha512Hash(password, salt);
            String passHashHex = passHash.toHex();
            Hash aktHash = new Sha1Hash(email);
            String aktHashHex = aktHash.toHex();
            osoba.setAktHash(aktHashHex);
            em.getTransaction().begin();
            Osoba osobaFromDB = getOsobaWOHesloAktHex(email);
            if (osobaFromDB == null || !email.equals(osobaFromDB.getEmail())) {
                em.persist(osoba);
                em.getTransaction().commit();
                return true;
            } else {
                em.getTransaction().commit();
                return false;
            }
        } catch (Exception e) {
            log.log(Level.WARNING, e.getMessage());
            em.getTransaction().rollback();
            return false;
        } finally {
            em.close();
        }
    }

    public String getAktHash(String email) {
        EntityManager em = emf.createEntityManager();
        try {
            Osoba osoba = new Osoba();
            Query query = em.createNativeQuery("SELECT akt_hash FROM " + DAO.t(Osoba.class) + " WHERE email = :email ");
            query.setParameter("email", email);
            List list = query.getResultList();
            String aktHash = (String) list.get(0);
            return aktHash;
        } catch (Exception e) {
            log.log(Level.WARNING, e.getMessage());
            return "";
        } finally {
            em.close();
        }
    }

}
